﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Net;
using System.Xml.XPath;
using System.IO;
using System.Xml;
using System.Globalization;

namespace CasterDPSMeter
{
    public partial class CharacterSelector : Form
    {
        private List<Region> _regions;

        public CharacterSelector()
        {
            InitializeComponent();
            _regions = new List<Region>();
        }

        private void CharacterSelector_Load(object sender, EventArgs e)
        {
            _regions.Add(new Region { Name = "US & Oceanic", BaseUrl = "http://www.wowarmory.com" });
            _regions.Add(new Region { Name = "Europe", BaseUrl = "http://eu.wowarmory.com" });
            _regions.Add(new Region { Name = "Korean", BaseUrl = "http://kr.wowarmory.com" });
            _regions.Add(new Region { Name = "China", BaseUrl = "http://cn.wowarmory.com" });
            _regions.Add(new Region { Name = "Taïwan", BaseUrl = "http://tw.wowarmory.com" });

            region.DataSource = _regions;
            region.DisplayMember = "Name";
            region.ValueMember = "BaseUrl";
        }

        public Player GetPlayerFromArmory()
        {
            string url1 = region.SelectedValue.ToString();
            string url2 = region.SelectedValue.ToString();
            url1 += "/character-sheet.xml?r={0}&n={1}";
            url2 += "/character-talents.xml?r={0}&n={1}";
            url1 = string.Format(url1, realm.Text, character.Text);
            url2 = string.Format(url2, realm.Text, character.Text);

            string xml1 = GetXmlFromUrl(url1);
            string xml2 = GetXmlFromUrl(url2);

            Player player = new Player();
            player.BonusDamage.Arcane = GetInt32FromXml(xml1, "/page/characterInfo/characterTab/spell/bonusDamage/arcane/@value");
            player.BonusDamage.Fire = GetInt32FromXml(xml1, "/page/characterInfo/characterTab/spell/bonusDamage/fire/@value");
            player.BonusDamage.Frost = GetInt32FromXml(xml1, "/page/characterInfo/characterTab/spell/bonusDamage/frost/@value");
            player.BonusDamage.Holy = GetInt32FromXml(xml1, "/page/characterInfo/characterTab/spell/bonusDamage/holy/@value");
            player.BonusDamage.Nature = GetInt32FromXml(xml1, "/page/characterInfo/characterTab/spell/bonusDamage/nature/@value");
            player.BonusDamage.Shadow = GetInt32FromXml(xml1, "/page/characterInfo/characterTab/spell/bonusDamage/shadow/@value");

            player.BonusHealing = GetInt32FromXml(xml1, "/page/characterInfo/characterTab/spell/bonusHealing/@value");

            player.HitRating = GetInt32FromXml(xml1, "/page/characterInfo/characterTab/spell/hitRating/@value");

            player.CritChance.Arcane = GetDoubleFromXml(xml1, "/page/characterInfo/characterTab/spell/critChance/arcane/@percent");
            player.CritChance.Fire = GetDoubleFromXml(xml1, "/page/characterInfo/characterTab/spell/critChance/fire/@percent");
            player.CritChance.Frost = GetDoubleFromXml(xml1, "/page/characterInfo/characterTab/spell/critChance/frost/@percent");
            player.CritChance.Holy = GetDoubleFromXml(xml1, "/page/characterInfo/characterTab/spell/critChance/holy/@percent");
            player.CritChance.Nature = GetDoubleFromXml(xml1, "/page/characterInfo/characterTab/spell/critChance/nature/@percent");
            player.CritChance.Shadow = GetDoubleFromXml(xml1, "/page/characterInfo/characterTab/spell/critChance/shadow/@percent");

            player.Intellect = GetInt32FromXml(xml1, "/page/characterInfo/characterTab/baseStats/intellect/@effective");

            player.Talents = GetStringFromXml(xml2, "/page/characterInfo/talentTab/talentTree/@value");

            player.SpellHasteRating = 0; // ???

            return player;
        }

        private string GetXmlFromUrl(string url)
        {
            WebClient wc = new WebClient();
            wc.Headers.Add(HttpRequestHeader.UserAgent, "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.0.1) Gecko/2008070208 Firefox/3.0.1");
            wc.Headers.Add(HttpRequestHeader.Accept, "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8");
            wc.Headers.Add(HttpRequestHeader.AcceptLanguage, "en-us,en;q=0.5");
            wc.Headers.Add(HttpRequestHeader.AcceptCharset, "ISO-8859-1,utf-8;q=0.7,*;q=0.7");
            wc.Encoding = Encoding.UTF8;
            string data = wc.DownloadString(url);
            return data;
        }

        private string GetStringFromXml(string xml, string xpath)
        {
            byte[] xmlBuffer = Encoding.UTF8.GetBytes(xml);
            using (MemoryStream ms = new MemoryStream(xmlBuffer))
            {
                using (XmlTextReader xmlReader = new XmlTextReader(ms))
                {
                    XPathDocument doc = new XPathDocument(xmlReader);
                    XPathNavigator nav = doc.CreateNavigator();
                    XPathNodeIterator nodes = (XPathNodeIterator)nav.Evaluate(xpath);
                    nodes.MoveNext();
                    string value = nodes.Current.Value;
                    return value;
                }
            }
        }

        private int GetInt32FromXml(string xml, string xpath)
        {
            byte[] xmlBuffer = Encoding.UTF8.GetBytes(xml);
            using (MemoryStream ms = new MemoryStream(xmlBuffer))
            {
                using (XmlTextReader xmlReader = new XmlTextReader(ms))
                {
                    XPathDocument doc = new XPathDocument(xmlReader);
                    XPathNavigator nav = doc.CreateNavigator();
                    XPathNodeIterator nodes = (XPathNodeIterator)nav.Evaluate(xpath);
                    nodes.MoveNext();
                    string tmp = nodes.Current.Value;
                    int value = Int32.Parse(tmp);
                    return value;
                }
            }
        }

        private double GetDoubleFromXml(string xml, string xpath)
        {
            byte[] xmlBuffer = Encoding.UTF8.GetBytes(xml);
            using (MemoryStream ms = new MemoryStream(xmlBuffer))
            {
                using (XmlTextReader xmlReader = new XmlTextReader(ms))
                {
                    XPathDocument doc = new XPathDocument(xmlReader);
                    XPathNavigator nav = doc.CreateNavigator();
                    XPathNodeIterator nodes = (XPathNodeIterator)nav.Evaluate(xpath);
                    nodes.MoveNext();
                    string tmp = nodes.Current.Value;
                    double value = Double.Parse(tmp, CultureInfo.CreateSpecificCulture("en-US"));
                    return value;
                }
            }
        }
    }
}
